/**
 * 定时器
 * @param id    定时器id，自定义
 * @param aminTime  执行间隔时间
 * @param callback  定时执行的函数，返回callback(id,runtime)，id是定时器的时间，runtime是当前运行的时间
 * @param maxTime   定时器重复执行的最大时长
 * @param afterTimeUp   定时器超时之后的回调函数，返回afterTimeUp(id,usedTime,countTimes)，id是定时器的时间，usedTime是定时器执行的总时间，countTimes是当前定时器运行的回调次数
 */
function runTimer(id, aminTime, callback, maxTime, afterTimeUp) {
    let startTime = 0; // 记录开始时间
    let countTimes = 0; // 记录回调函数执行的次数
    let timer; // 定时器变量

    /**
     * 获取当前时间
     * @returns {number}
     */
    function getTime() {
        return new Date().getTime();
    }

    function timeout(diffTime) {
        // 执行间隔 = 下一次执行时间点 + 执行时间
        let runtime = aminTime - diffTime; // 计算下一次的执行间隔
        if (runtime < 0) runtime = 0; // 防止负数时间间隔

        timer = setTimeout(() => {
            let usedTime = getTime() - startTime; // 计算已用时间
            if (usedTime >= maxTime) { // 如果已用时间超过了最大时长
                clearTimeout(timer); // 清除定时器
                afterTimeUp(id, usedTime, countTimes); // 调用超时后的回调函数
                return;
            }

            // 执行回调函数
            callback(id, runtime, countTimes);
            countTimes++; // 增加回调次数

            // 更新时间并计算下一次需要扣除的时间
            let tmp = startTime;
            startTime = getTime();
            diffTime = (startTime - tmp) - aminTime;

            // 继续下一次调用
            timeout(diffTime);
        }, runtime);
    }

    // 启动定时器
    startTime = getTime(); // 初始化开始时间
    timeout(0); // 开始第一次调用
}
